/***************************************************************************
 *   Copyright (C) 2009 by Zheng Yonglei
 *   zhengyonglei@gmail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "TestWidget.h"

#include "Options.h"
#include "Logger.h"

TestWidget::TestWidget(QWidget *parent)
    : QWidget(parent),
    mDictAreaWidthRate(0.6f),
    mTestProgress(TP_None),
    mMsElapsed(0)
{
	ui.setupUi(this);

	//set promptor
	ui.testPromptor->setReadOnly(true);
	ui.testPromptor->setOpenLinks(false);
	QObject::connect(ui.testPromptor, SIGNAL(anchorClicked(const QUrl&)),
				this, SLOT(anchorClicked(const QUrl&)));

	//set dictionary
	mDictionary = new Dictionary(this);
	QGridLayout* dictLayout = new QGridLayout(ui.dictionaryWidget);
	dictLayout->setContentsMargins(0, 0, 0, 0);
	dictLayout->addWidget(mDictionary);

	//set timer
	QObject::connect(&mTimer, SIGNAL(timeout()), this, SLOT(timeout()));

	showDictionary(false);
}

TestWidget::~TestWidget()
{

}

bool TestWidget::prepareToTest()
{
	if (!mTestManager.prepareToTest())
		return false;

	if(mTestManager.testNextWord())
	{
		mTestManager.setReviewFrequency();
		mTestManager.initActivatedWordTotalTestCount();

		emit updateMainBulletin();
		begin();
		return true;
	}
	else
		return false;
}

void TestWidget::setDisplayFont(QFont& font)
{
	ui.testPromptor->setFont(font);
	mDictionary->setDisplayFont(font);
}

void TestWidget::testNextWord()
{
	LOG<<"<-------------Start a new cycle.------------->"<<endl;
	if(mTestManager.testNextWord())
	{
		emit updateMainBulletin();

		if (	mTestManager.getActivatedWordCount() == mTestManager.getFinishedWordCount()
			&& 	mTestManager.getTestFinishedFirstCount() ==0 )
		{
			if (endCurTest())
				return;
		}

		begin();
	}
}

bool TestWidget::endCurTest()
{
	TestEndDialog dialog;
	dialog.setFont(this->font());
	switch(dialog.exec())
	{
	case ST_End:
		emit curTestFinished();
		return true;
	case ST_OpenList:
		emit curTestFinished();
		emit showSelectListDialog();
		return true;
	case ST_Analyse:
		emit curTestFinished();
		emit showAnalysisDialog();
		return true;
	case ST_None:
		this->raise();
		this->activateWindow();
		return false;
	}

	return false;
}

void TestWidget::begin()
{
	ui.testPromptor->clear();
	TestWord* word = mTestManager.getCurTestWord();
	if (word)
	{
		mTestProgress = TP_Begin;

		QString msg;
		QTextStream ms(&msg);
		ms<<"<h1 align=\"left\"><a href=\"key:"<<word->word<<"\">"<<word->word<<"</h1><br>";
		ms<<tr("Do you remember this word?")<<"<br>";
		ms<<tr("Please answer within ")<<OPT.firstGroupWaitSecMax<<tr(" seconds.")<<" <br>";
		ms<<"<h4 align=\"left\"><a href=\"test:"<<ANS_YES<<"\"><font color='green'>"<<tr("Yes, I remember this word.")<<"</font></a></h4><br>";
		ms<<"<h4 align=\"left\"><a href=\"test:"<<ANS_NO<<"\"><font color='red'>"<<tr("No, I forget it.")<<"</font></a></h4><br>";
		ui.testPromptor->insertHtml(msg);

		showDictionary(false);

		mMsElapsed = 0;
		mTimer.start(100);
	}
	else
	{
		ui.testPromptor->insertHtml("<font color='red'>Fatal Error!</font>");
	}
}

void TestWidget::confirm()
{
	mTestProgress = TP_Confirm;

	ui.testPromptor->clear();
	ui.testPromptor->setWordInfo(&mTestManager, false);
	QString msg;
	QTextStream ms(&msg);
	ms<<"<br>";
	ms<<tr("Do you remember this word correctly?")<<"<br>";
	ms<<"<h4 align=\"left\"><a href=\"test:"<<CFM_YES<<"\"><font color='green'>"<<tr("Yes, I remember it correctly.")<<"</font></a></h4><br>";
	ms<<"<h4 align=\"left\"><a href=\"test:"<<CFM_NO<<"\"><font color='red'>"<<tr("No, I do not.")<<"</font></a></h4><br><br>";
	ui.testPromptor->insertHtml(msg);

	showDictionary(true);
	TestWord* word = mTestManager.getCurTestWord();
	if (word) quickLookupDictionary(word->word);

	mMsElapsed = 0;
	mTimer.start(100);
}

void TestWidget::testPassed()
{
	mTestProgress = TP_Finish;
	mTimer.stop();

	mTestManager.testPassed();

	ui.testPromptor->clear();
	ui.testPromptor->insertHtml(tr("You <font color='green'>PASSED</font> the test.<br>"));
	ui.testPromptor->setWordInfo(&mTestManager, false);
	QString msg;
	QTextStream ms(&msg);
	ms<<"<h4 align=\"left\"><a href=\"test:"<<TEST_NEXT<<"\"><font color='green'>"<<tr("Next word")<<"</font></a></h4><br><br>";
	ui.testPromptor->insertHtml(msg);

	showDictionary(true);
	TestWord* word = mTestManager.getCurTestWord();
	if (word) quickLookupDictionary(word->word);}

void TestWidget::testFailed(QString reason)
{
	mTestProgress = TP_Finish;
	mTimer.stop();

	mTestManager.testFailed();

	ui.testPromptor->clear();
	if (reason.isEmpty())
		ui.testPromptor->insertHtml(tr("You <font color='red'>FAILED</font> the test.<br>"));
	else
		ui.testPromptor->insertHtml(reason + QString("<br>"));
	ui.testPromptor->setWordInfo(&mTestManager, false);
	QString msg;
	QTextStream ms(&msg);
	ms<<"<h4 align=\"left\"><a href=\"test:"<<TEST_NEXT<<"\"><font color='green'>"<<tr("Next word")<<"</font></a></h4><br><br>";
	ui.testPromptor->insertHtml(msg);

	showDictionary(true);
	TestWord* word = mTestManager.getCurTestWord();
	if (word) quickLookupDictionary(word->word);
}

void TestWidget::showDictionary(bool showDict)
{
	QList<int> size;
	float width = this->width();
	if (showDict)
	{
		size<<width*(1 - mDictAreaWidthRate)<<width*mDictAreaWidthRate;
		ui.splitter->setSizes(size);
	}
	else
	{
		size<<width<<0;
		ui.splitter->setSizes(size);
	}
}

void TestWidget::quickLookupDictionary(QString key)
{
	mDictionary->setLookupDelayMS(0);
	mDictionary->setInput(key);
	mDictionary->setLookupDelayMS(500);
	if (OPT.autoSpeak)
		mDictionary->speak(key);
}

void TestWidget::timeout()
{
	if (OPT.isPaused)
		return;

	mMsElapsed += mTimer.interval();
	//LOG<<"mMsElapsed="<<mMsElapsed<<endl;
	switch(mTestProgress)
	{
	case TP_None:
	case TP_Finish:
		break; //do nothing
	case TP_Begin:
		if (mMsElapsed >= OPT.firstGroupWaitSecMax*1000) //fail the test
		{
			testFailed(tr("You <font color='red'>FAILED</font> the test because your time is out."));
			mTimer.stop();
		}
		break;
	case TP_Confirm:
		if (mMsElapsed >= OPT.secondGroupWaitSecMin*1000)
		{
			mTimer.stop();
		}
		break;
	}
}

void TestWidget::anchorClicked(const QUrl& url)
{
	QString url_s = url.toString();
	QString type = url_s.left(url_s.indexOf(":"));
	type = type.simplified();
	QString content = url_s.right(url_s.size() - url_s.indexOf(":") - 1);
	content = content.simplified();
	if (type == "key")
		quickLookupDictionary(content);
	else if (type == "test")
	{
		//LOG<<"Test:"<<content<<endl;
		if (content == ANS_YES)
		{
			confirm();
		}
		else if (content == ANS_NO)
		{
			testFailed();
		}
		else if (content == CFM_YES)
		{
			if (!mTimer.isActive())
				testPassed();
		}
		else if (content == CFM_NO)
		{
			if (!mTimer.isActive())
				testFailed();
		}
		else if (content == TEST_NEXT)
		{
			testNextWord();
		}
		else
			LOG<<"Invalid content: "<<content<<endl;
	}
}
